#include "fifo/mTimer.h"
#include <string.h>
#include <fstream>

using namespace std;

extern uint8_t flag_Aperiodic;
uint8_t flag_Time=0;

static bool readConfigFile(const string filename);

#define priority_len 4
uint8_t new_priority[priority_len];
const string filename="/home/ros-18/Qt/program/setconfig/config_file";
uint8_t priority[priority_len]={33,74,30,24};//priority list
uint8_t priority_counts=1;
bool same_flag=0;

uint8_t out_fifo[priority_len]={0,0,0,0};
uint8_t out_count=0;

mTimer * mTimer::Timer=NULL;
void G_TimeOut(int signo)
{
    mTimer * t=	mTimer::getInstance();
    t->TimeOut();
}

mTimer::mTimer()
{
	_p=0;
        mT_p=0;
}
void
mTimer::AddHander(Message_FIFO_WR_T * test,void(Message_FIFO_WR_T:: * f)())
{
	_handler[_p].test=test;
	_handler[_p].f=f;
	_p++;
        for(uint8_t i=0;i<_p;i++)
        {
           _handler[i].test->cls_Tcount();
        }
        priority_counts=1;
}

void mTimer::start(int interval)
{
	struct itimerval tick;
	signal(SIGALRM,G_TimeOut);
	memset(&tick,0,sizeof(tick));
        tick.it_value.tv_sec=0;
	tick.it_value.tv_usec=1;
	tick.it_interval.tv_sec=0;
	tick.it_interval.tv_usec=interval*1000;
	if(setitimer(ITIMER_REAL,&tick,NULL)< 0)
		printf("Set Timer Failed!");
}

void mTimer::ch_priority(uint8_t *priority_temp=priority)
{
    FunC temp;
    uint8_t id;
    int i;
    int j;
    int k=0;

    for(i=0;i<priority_len;i++)
    {
        id=priority_temp[i];
        for(j=k;j<_p;j++)
        {
            if(_handler[j].test->getID()==id)
            {
                temp=_handler[k];
                _handler[k]=_handler[j];
                _handler[j]=temp;
                k++;
                break;
            }
        }
    }
}

void mTimer::TimeOut()
{
    //printf("T\n");
    int i;
    int j;


    if(flag_Aperiodic==1)
    {
        flag_Time=1;
        return;
    }
    if(priority_counts%10==0)
    {
        struct timeval tv;
        struct timezone tz;
        struct tm *p;
        gettimeofday(&tv,&tz);
        p=localtime(&tv.tv_sec);
        int second =p->tm_sec;
        int msec = tv.tv_usec;
        printf("******%d:%d   ",second,msec/1000);

        readConfigFile(filename);//!!!Attention:priority_counts will chance,priority_counts=0!!!!!
        if(same_flag==0);
        {
            ch_priority();//10s change fifo_priority by priority[7]
        }
        priority_counts=1;
        statistics_printf();
    }
    else
    {
        priority_counts++;
    }

    for(i=0;i<_p;i++)
       {
           //printf("%d %d:%d",i,_handler[i].test->getTimer_count(),_handler[i].test->gettime_num());
           if(_handler[i].test->getTimer_count()%_handler[i].test->gettime_num()==0)
           {
               out_fifo[out_count]=i;
               out_count++;
           }

       }

    if(out_count>0&&_p>0)
    {
       Mes_Time time_store;
       Mes_Time time_temp;
       int Time_Results[BUFSIZE];
       int time_result=2000;
       uint8_t mes_dex;
       _handler[out_fifo[0]].test->set_outmessage(1,0);
       time_store.second=_handler[0].test->message_time[2].second;
       time_store.msec=(_handler[0].test->message_time[2].msec)/1000;
       //printf("store_Time=%d:%d\n",time_store.second,time_store.msec);

        for(i=1;i<out_count;i++)
       {
           for(j=0;j<BUFSIZE;j++)
           {
               time_temp.second=_handler[i].test->message_time[j].second;
               time_temp.msec=(_handler[i].test->message_time[j].msec)/1000;
               //printf("temp_Time=%d:%d   ",time_temp.second,time_temp.msec);
               Time_Results[j]=(time_store.second-time_temp.second)*1000+(time_store.msec-time_temp.msec);
               if(Time_Results[j]<0)
               {
                   Time_Results[j]=0-Time_Results[j];
               }
               //printf("Time_results=%d\n",Time_Results[j]);
               if(Time_Results[j]<time_result)
               {
                  time_result=Time_Results[j];
                  mes_dex=j;
               }
           }
           printf("Between_Time=%d,mes_dex=%d\n",time_result,mes_dex);
           _handler[out_fifo[i]].test->set_outmessage(1,BUFSIZE-1-mes_dex);
           time_result=2000;
        }
    }

    for(i=0;i<_p;i++)
    {
        //printf("p=%d:",i);
        //_handler[i].test->set_outmessage(1,2);
        (_handler[i].test->*_handler[i].f)();
    }
    out_count=0;
    printf("exit\n");
}
mTimer *
mTimer::getInstance()
{
	if(Timer==0)
	{
	  Timer=new mTimer;
	}
	return Timer;
}

static bool readConfigFile(const string filename)
{
   uint8_t count=0;
   uint8_t i=0;
   uint8_t k=0;
   char temp[3]={0,0,0};
   ifstream in;
   in.open(filename);
   if(!in) {
        printf("Can't open the file!\n");
        return false;
     }
   char ch;
   while(!in.eof())
   {
        in.read(&ch,1);
        if(ch==','||ch==' '||ch=='#')
        {
            if(k==3)
            {
               new_priority[i]=(temp[0]-48)*100+(temp[1]-48)*10+(temp[2]-48);
            }
            else if(k==2)
            {
               new_priority[i]=(temp[0]-48)*10+(temp[1]-48);
            }
            else if(k==1)
            {
               new_priority[i]=(temp[0]-48);
            }
            k=0;
            i++;
            if(new_priority[i]==priority[i])
            {
                count++;
            }
        }
        else if((ch>='0')&&(ch<='9'))
        {
            temp[k]=ch;
            k++;
        }
   }
   if(count==priority_len)
   {
      same_flag=1;
   }
   else
   {
      for(i=0;i<7;i++)
      {
           priority[i]=new_priority[i];
           same_flag=0;
      }
    }
   in.close();
}

void mTimer::statistics_printf()
{
    int i;
    int all_count=0;
    int all_Byte=0;
    int temp_count=0;
    int temp_Byte=0;
    printf("This Second Sened Message:\n");
    for(i=0;i<mT_p;i++)
    {
        temp_count=mT_message[i]->data_count;
        temp_Byte=mT_message[i]->message_len;
        printf("Message_ID:  %d  has sended  %d  message_packets: total  %d  Byte\n",mT_message[i]->getID(),temp_count,temp_count*temp_Byte);
        all_count=all_count+temp_count;
        all_Byte=all_Byte+temp_count*temp_Byte;
        mT_message[i]->data_count=0;
    }
    printf("This Second Sened All  %d  message_packets:  %d  Byte\n",all_count,all_Byte);

}

 void mTimer::add_mTmessage(Message_FIFO_WR_T* m)
 {
    mT_message[mT_p++]=m;
 }
